/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package imagemanip.structures;

import java.awt.Color;
import java.util.LinkedList;

/**
 *
 * @author judu
 */
public final class ColorEditor {


    private static int dist = 5;

    public static int getDist() {
        return dist;
    }

    public static void setDist(int dist) throws Exception {
        if(dist < 0 || dist > 255){
            throw new Exception("Valeur interdite, il faut que la distance soit comprise entre 0 et 255");
        } else {
            ColorEditor.dist = dist;
        }
        
    }





    /**
     * Calcule la distance entre deux couleurs, en prenant la
     * plus variation monocomposante maximum, car elle est plus agréable à calculer,
     * et que le nom est sympa.
     * @param c1
     * @param c2
     * @return
     */
    public static int distanceColors(Color c1, Color c2) {

        if (c1 == null || c2 == null) {
            return 256;
        } else {
            int diffRouge = Math.abs(c1.getRed() - c2.getRed());
            int diffVert = Math.abs(c1.getGreen() - c2.getGreen());
            int diffBleu = Math.abs(c1.getBlue() - c2.getBlue());

            return Math.max(diffBleu, Math.max(diffVert, diffRouge));
        }

    }
    /**
     * Calcule la distance entre les couleurs les plus éloignées des 4 fournies en paramètre
     * @param c1
     * @param c2
     * @param c3
     * @param c4
     * @return
     */
    public static int distance4Colors(Color c1, Color c2, Color c3, Color c4){

        int m1 = Math.max(distanceColors(c1, c2), distanceColors(c1, c3));
        int m2 = Math.max(m1, distanceColors(c1, c4));
        int m3 = Math.max(distanceColors(c2, c3), distanceColors(c2, c4));
        m1 = Math.max(m3, distanceColors(c3, c4));

        return(Math.max(m2, m1));
    }

    
    private static Color moyenne2Colors(Color c1, Color c2) {
        if (c1 == null) {
            if (c2 == null) {
                return null;
            } else {
                return c2;
            }
        } else {
            if (c2 == null) {
                return c1;
            } else {
                return new Color((c1.getRed() + c2.getRed()) / 2, (c1.getGreen() + c2.getGreen()) / 2, (c1.getBlue() + c2.getBlue()) / 2);
            }
        }
    }

    public static Color moyenne4Colors(Color c1, Color c2, Color c3, Color c4) {
        return moyenne2Colors(moyenne2Colors(c1, c2), moyenne2Colors(c3, c4));
    }


    /**
     * Renvoie la moyenne pondérée des deux OcTreeElement passés.
     * @param c1
     * @param c2
     * @return
     */
    private static OcTreeElement moyenne2ColorsPonderation(OcTreeElement c1, OcTreeElement c2) {
        if (c1 == null) {
            if (c2 == null) {
                return null;
            } else {
                return c2;
            }
        } else {
            if (c2 == null) {
                return c1;
            } else {
                return new OcTreeElement(new Color((c1.getCouleur().getRed()*c1.getOccurence() + c2.getCouleur().getRed()*c1.getOccurence()) / (c1.getOccurence() + c2.getOccurence()), (c1.getCouleur().getGreen()*c1.getOccurence() + c2.getCouleur().getGreen()*c2.getOccurence()) / (c1.getOccurence() + c2.getOccurence()), (c1.getCouleur().getBlue() + c2.getCouleur().getBlue()) / (c1.getOccurence() + c2.getOccurence())), (c1.getOccurence() + c2.getOccurence()));
            }
        }
    }

    /**
     * Retourne un OcTree moyenne d'une liste d'OcTree
     * @param couleurs
     * @return
     */
    public static OcTreeElement moyenneListeColorsPonderation(LinkedList<OcTreeElement> couleurs) {
        OcTreeElement c1 = couleurs.get(0);
        for (int i = 1; i<= couleurs.size() ; i++) {
            OcTreeElement c2 = couleurs.get(i);
            c1 = moyenne2ColorsPonderation(c1, c2);
        }
        return c1;
    }

    /**
     * Renvoie la couleur la plus proche d'une couleur donnée en paramètre
     * @param c : Couleur dont on veut une voisine
     * @param couleurs : liste des couleurs à comparer à c
     * @return la couleur la plus proche de c
     */
    public static Color colorMinDist(Color c, LinkedList<OcTreeElement> couleurs) {
        int d = distanceColors(c, couleurs.get(0).getCouleur());
        Color coulretour = couleurs.get(0).getCouleur();
        for (int i=1; i< couleurs.size(); i++) {
            if (d > distanceColors(c, couleurs.get(i).getCouleur())) {
                d = distanceColors(c,couleurs.get(i).getCouleur());
                coulretour = couleurs.get(i).getCouleur();
            }
        }
        return coulretour;
    }

}
